unit SynOptionsDlg;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, ImgList, ComCtrls, ExtCtrls, Grids,SynEditSource,
  SynEdit, SynEditMiscClasses, SynEditTypes;

{$I SynEdit.inc}

type
  TSynOptionsForm = class(TForm)
    Button3: TButton;
    Button2: TButton;
    Button1: TButton;
    PageControl1: TPageControl;
    TabSheet1: TTabSheet;
    sTabWidth: TEdit;
    Label1: TLabel;
    sBlockWidth: TEdit;
    cbSelectmode: TComboBox;
    Label8: TLabel;
    GroupBox4: TGroupBox;
    soAltSetsColumnMode: TCheckBox;
    soAutoIndent: TCheckBox;
    soDragDropEditing: TCheckBox;
    soDropFiles: TCheckBox;
    soGroupUndo: TCheckBox;
    soShowSpecialChars: TCheckBox;
    soSmartTabs: TCheckBox;
    soSmartTabDelete: TCheckBox;
    soTabIndent: TCheckBox;
    soTabsToSpace: TCheckBox;
    cbInsertMode: TCheckBox;
    cbCodeFolding: TCheckBox;
    cbPastEol: TCheckBox;
    CheckBox1: TCheckBox;
    sMaxUndo: TEdit;
    Label2: TLabel;
    sMaxScroll: TEdit;
    Label6: TLabel;
    Label3: TLabel;
    TabSheet3: TTabSheet;
    TabSheet4: TTabSheet;
    GroupBox6: TGroupBox;
    sShowLineDivder: TCheckBox;
    sShowActiveLine: TCheckBox;
    sShowGutter: TCheckBox;
    sShowRightEdge: TCheckBox;
    sRightEdgeMouseMove: TCheckBox;
    sShowLineNumber: TCheckBox;
    LabelRightEdgePos: TLabel;
    sRightEdgePos: TEdit;
    sWordWrap: TCheckBox;
    LabelWordwrapStyle: TLabel;
    sWordwrapStyle: TComboBox;
    sWordwrapPos: TEdit;
    LabelWordwrapPos: TLabel;
    GroupBox9: TGroupBox;
    Label5: TLabel;
    BackColorBox: TColorBox;
    Label7: TLabel;
    SelTextColorBox: TColorBox;
    Label10: TLabel;
    SelBackColorBox: TColorBox;
    Label11: TLabel;
    CurTextColorBox: TColorBox;
    CurBackColorBox: TColorBox;
    Label12: TLabel;
    GroupBox1: TGroupBox;
    LabelLineSpacingRule: TLabel;
    sLineSpacingRule: TComboBox;
    LabelLineSpacing: TLabel;
    sLineSpacing: TEdit;
    Label9: TLabel;
    sFontNameCom: TComboBox;
    Label13: TLabel;
    sFontsizeCom: TComboBox;
    FontPreview: TPanel;
    Label4: TLabel;
    procedure CurBackColorBoxChange(Sender: TObject);
    procedure CurTextColorBoxChange(Sender: TObject);
    procedure SelBackColorBoxChange(Sender: TObject);
    procedure SelTextColorBoxChange(Sender: TObject);
    procedure BackColorBoxChange(Sender: TObject);
    procedure sFontsizeComChange(Sender: TObject);
    procedure sFontNameComChange(Sender: TObject);
    procedure cbInsertModeClick(Sender: TObject);
    procedure cbSelectmodeChange(Sender: TObject);
    procedure cbCodeFoldingClick(Sender: TObject);
    procedure cbPastEolClick(Sender: TObject);
    procedure CheckBox1Click(Sender: TObject);
    procedure sLineNumberStartKeyDown(Sender: TObject; var Key: Word;
      Shift: TShiftState);
    procedure Button3Click(Sender: TObject);
    procedure Button5Click(Sender: TObject);
    procedure sBlockWidthChange(Sender: TObject);
    procedure sLineSpacingChange(Sender: TObject);
    procedure sLineSpacingRuleChange(Sender: TObject);
    procedure sMaxScrollChange(Sender: TObject);
    procedure sMaxUndoChange(Sender: TObject);
    procedure soAltSetsColumnModeClick(Sender: TObject);
    procedure soAutoIndentClick(Sender: TObject);
    procedure soDragDropEditingClick(Sender: TObject);
    procedure soDropFilesClick(Sender: TObject);
    procedure soGroupUndoClick(Sender: TObject);
    procedure soShowSpecialCharsClick(Sender: TObject);
    procedure soSmartTabDeleteClick(Sender: TObject);
    procedure soSmartTabsClick(Sender: TObject);
    procedure soTabIndentClick(Sender: TObject);
    procedure soTabsToSpaceClick(Sender: TObject);
    procedure sRightEdgeMouseMoveClick(Sender: TObject);
    procedure sRightEdgePosChange(Sender: TObject);
    procedure sShowActiveLineClick(Sender: TObject);
    procedure sShowGutterClick(Sender: TObject);
    procedure sShowLineDivderClick(Sender: TObject);
    procedure sShowLineNumberClick(Sender: TObject);
    procedure sShowRightEdgeClick(Sender: TObject);
    procedure sTabWidthChange(Sender: TObject);
    procedure sWordWrapClick(Sender: TObject);
    procedure sWordwrapPosChange(Sender: TObject);
    procedure sWordwrapStyleChange(Sender: TObject);
    procedure FormCreate(Sender: TObject);
  private
    FDefault, Source : TSynEditSource;
    procedure SetOptions(checked : Boolean; Option : TSynEditorOption);
    function GetOptions(Option : TSynEditorOption): Boolean;
  public
    { Public declarations }
    procedure SetValue(Source : TSynEditSource);
    procedure Execute(default : TSynEditSource; SynEdit : TCustomSynEdit);
  end;

var
  SynOptionsForm: TSynOptionsForm;

implementation

{$R *.dfm}

procedure TSynOptionsForm.sLineSpacingChange(Sender: TObject);
begin
  Source.LineSpacing := StrToInt(sLineSpacing.Text);
end;

procedure TSynOptionsForm.sLineSpacingRuleChange(Sender: TObject);
begin
  Source.LineSpacingRule := TLineSpacingRule(sLineSpacingRule.ItemIndex)
end;

procedure TSynOptionsForm.sShowGutterClick(Sender: TObject);
begin
  Source.Gutter.Visible := sShowGutter.Checked;
end;

procedure TSynOptionsForm.sShowLineNumberClick(Sender: TObject);
begin
  Source.Gutter.ShowLineNumbers := sShowLineNumber.Checked;
end;

procedure TSynOptionsForm.sWordwrapStyleChange(Sender: TObject);
begin
  if sWordwrapStyle.ItemIndex in [0..2] then
    source.WordWrap.Style := TSynWordWrapStyle(sWordwrapStyle.ItemIndex)
end;

procedure TSynOptionsForm.sWordwrapPosChange(Sender: TObject);
begin
  Source.WordWrap.Position := StrToInt(sWordwrapPos.Text);
end;

procedure TSynOptionsForm.sShowRightEdgeClick(Sender: TObject);
begin
  Source.RightEdge.Visible := sShowRightEdge.Checked;
end;

procedure TSynOptionsForm.sRightEdgePosChange(Sender: TObject);
begin
  source.RightEdge.Position := StrToInt(sRightEdgePos.Text);
end;

procedure TSynOptionsForm.sShowActiveLineClick(Sender: TObject);
begin
  source.ActiveLine.Visible := sShowActiveLine.Checked;
  source.ActiveLine.Indicator.Visible := sShowActiveLine.Checked;
end;

procedure TSynOptionsForm.sShowLineDivderClick(Sender: TObject);
begin
  Source.LineDivider.Visible := sShowLineDivder.Checked
end;

procedure TSynOptionsForm.sBlockWidthChange(Sender: TObject);
begin
  Source.BlockWidth := StrToInt(sBlockWidth.text)
end;

procedure TSynOptionsForm.sMaxUndoChange(Sender: TObject);
begin
  Source.MaxUndo := StrToInt(sMaxUndo.text)
end;

procedure TSynOptionsForm.sTabWidthChange(Sender: TObject);
begin
  Source.TabWidth := StrToInt(sTabWidth.text)
end;

procedure TSynOptionsForm.soAltSetsColumnModeClick(Sender: TObject);
begin
  SetOptions(soAltSetsColumnMode.Checked, eoAltSetsColumnMode);
end;

procedure TSynOptionsForm.SelBackColorBoxChange(Sender: TObject);
begin
  Source.SelectedColor.Background := selbackcolorbox.Selected;
end;

procedure TSynOptionsForm.SelTextColorBoxChange(Sender: TObject);
begin
  Source.SelectedColor.Foreground := seltextcolorbox.Selected;
end;

procedure TSynOptionsForm.SetOptions(checked: Boolean;
  Option: TSynEditorOption);
begin
  if checked then
     Source.Options := Source.Options + [Option]
  else Source.Options := Source.Options - [Option]
end;

procedure TSynOptionsForm.soAutoIndentClick(Sender: TObject);
begin
  SetOptions(soAutoIndent.Checked, eoAutoIndent);
end;

procedure TSynOptionsForm.soDragDropEditingClick(Sender: TObject);
begin
  SetOptions(soDragDropEditing.Checked, eoDragDropEditing);
end;

procedure TSynOptionsForm.soDropFilesClick(Sender: TObject);
begin
  SetOptions(soDropFiles.Checked, eoDropFiles);
end;

procedure TSynOptionsForm.soGroupUndoClick(Sender: TObject);
begin
  SetOptions(soGroupUndo.Checked, eoGroupUndo);
end;

procedure TSynOptionsForm.soShowSpecialCharsClick(Sender: TObject);
begin
  SetOptions(soShowSpecialChars.Checked, eoShowSpecialChars);
end;

procedure TSynOptionsForm.soSmartTabsClick(Sender: TObject);
begin
  SetOptions(soSmartTabs.Checked, eoSmartTabs);
end;

procedure TSynOptionsForm.soSmartTabDeleteClick(Sender: TObject);
begin
  SetOptions(soSmartTabDelete.Checked, eoSmartTabDelete);
end;

procedure TSynOptionsForm.soTabIndentClick(Sender: TObject);
begin
  SetOptions(soTabIndent.Checked, eoTabIndent);
end;

procedure TSynOptionsForm.soTabsToSpaceClick(Sender: TObject);
begin
  SetOptions(soTabsToSpace.Checked, eoTabsToSpaces);
end;


procedure TSynOptionsForm.Button5Click(Sender: TObject);
begin
  with TFontDialog.Create(Self) do
  begin
    Font := Source.Font;
    Options := Options + [fdFixedPitchOnly];
    if Execute then
    begin
      FontPreview.Font := font;
      Source.Font := Font;
      sFontSizeCom.Text := IntTostr(Font.Size);
      sFontNameCom.ItemIndex := sFontNameCom.Items.IndexOf(Font.Name);
    end;
  end;
end;

procedure TSynOptionsForm.cbCodeFoldingClick(Sender: TObject);
begin
  {$IFDEF CODEFOLDING}
  //### Code Folding ###
  Source.CodeFolding.Enabled := cbCodeFolding.Checked;
  //### End Code Folding ###
  {$ENDIF}
end;

procedure TSynOptionsForm.cbInsertModeClick(Sender: TObject);
begin
  Source.InsertMode := cbInsertMode.checked;
end;

procedure TSynOptionsForm.cbPastEolClick(Sender: TObject);
begin
  SetOptions(cbPastEol.Checked, eoScrollPastEol);
end;

procedure TSynOptionsForm.cbSelectmodeChange(Sender: TObject);
begin
  Source.SelectionMode := TSynSelectionMode(cbSelectmode.ItemIndex);
end;

procedure TSynOptionsForm.CheckBox1Click(Sender: TObject);
begin
  SetOptions(CheckBox1.Checked, eoColumnEditExtension);
end;

procedure TSynOptionsForm.CurBackColorBoxChange(Sender: TObject);
begin
  Source.ActiveLine.Background := curbackcolorbox.Selected;
end;

procedure TSynOptionsForm.CurTextColorBoxChange(Sender: TObject);
begin
  Source.ActiveLine.Foreground := curtextcolorbox.Selected;
end;

procedure TSynOptionsForm.BackColorBoxChange(Sender: TObject);
begin
  Source.Color := BackColorBox.Selected;
end;

procedure TSynOptionsForm.Execute(default: TSynEditSource;
  SynEdit: TCustomSynEdit);
begin
  FDefault := default;
  if not Assigned(synEdit) then
    Source.Assign(Default)
  else
    Source.Assign(SynEdit);
   SetValue(Source);
  If ShowModal = mrok then
    if not Assigned(synEdit) then
      Default.Assign(Source)
    else
      Source.AssignTo(SynEdit);
end;

procedure TSynOptionsForm.Button3Click(Sender: TObject);
begin
  if FDefault <> nil then
    FDefault.Assign(Source);
end;

procedure TSynOptionsForm.SetValue(Source: TSynEditSource);
begin
  {$IFDEF CODEFOLDING}
  //### Code Folding ###
  cbCodeFolding.Visible := true;
  cbCodeFolding.Checked := Source.CodeFolding.Enabled;
  //### End Code Folding ###
  {$ENDIF}
  cbSelectMode.ItemIndex := integer(Source.SelectionMode);
  sBlockWidth.Text := IntToStr(Source.BlockWidth);
  sMaxUndo.Text := IntToStr(Source.MaxUndo);
  sTabWidth.Text := IntToStr(Source.TabWidth);
  sMaxScroll.Text := IntToStr(Source.MaxScrollWidth);
  sLineSpacingRule.ItemIndex := Integer(Source.LineSpacingRule);
  sLineSpacing.Text := IntToStr(Source.LineSpacing);
  sShowGutter.Checked := Source.Gutter.Visible;
  sShowLineNumber.Checked := Source.Gutter.ShowLineNumbers;
  sWordwrapStyle.ItemIndex := Integer(Source.WordWrap.Style);
  sWordWrap.Checked := Source.WordWrap.Enabled;
  sWordwrapPos.Text := IntToStr(Source.WordWrap.Position);
  sShowRightEdge.Checked := Source.RightEdge.Visible;
  sRightEdgeMouseMove.Checked := Source.RightEdge.MouseMove;
  sRightEdgePos.Text := IntToStr(Source.RightEdge.Position);
  sShowActiveLine.Checked := Source.ActiveLine.Visible;
  sShowLineDivder.Checked := Source.LineDivider.Visible;
  soAltSetsColumnMode.Checked := GetOptions(eoAltSetsColumnMode);
  soAutoIndent.Checked := GetOptions(eoAutoIndent);
  soDragDropEditing.Checked := GetOptions(eoDragDropEditing);
  soDropFiles.Checked := GetOptions(eoDropFiles);
  soGroupUndo.Checked := GetOptions(eoGroupUndo);
  soShowSpecialChars.Checked := GetOptions(eoShowSpecialChars);
  soSmartTabs.Checked := GetOptions(eoSmartTabs);
  soSmartTabDelete.Checked := GetOptions(eoSmartTabDelete);
  soTabIndent.Checked := GetOptions(eoTabIndent);
  soTabsToSpace.Checked := GetOptions(eoTabsToSpaces);
  Checkbox1.Checked := Getoptions(eoColumnEditExtension);
  cbpasteol.Checked := Getoptions(eoScrollPastEol);
  cbInsertMode.checked := Source.InsertMode;
  FontPreview.Font := Source.Font;
  sFontNameCom.ItemIndex := sFontNameCom.Items.IndexOf(Source.font.Name);
  sFontSizeCom.Text := IntToStr(Source.Font.Size);
  backcolorbox.Selected := Source.Color;
  seltextcolorbox.Selected := source.SelectedColor.Foreground;
  selbackcolorbox.Selected := source.SelectedColor.Background;
  curtextcolorbox.Selected := source.ActiveLine.Foreground;
  curbackcolorbox.Selected := source.ActiveLine.Background;
end;

function TSynOptionsForm.GetOptions(Option: TSynEditorOption): Boolean;
begin
  result := Option in Source.Options;
end;

var PixelsPerInch : integer;

function EnumFontName(var EnumLogFont: TEnumLogFont;
  var TextMetric: TNewTextMetric;
  FontType: Integer; Data: LPARAM): Integer;
  export; stdcall;
var
  FaceName: string;
begin
  FaceName := StrPas(EnumLogFont.elfLogFont.lfFaceName);
  with TStrings(Data) do
  begin
    if (IndexOf(FaceName) < 0) and
      ((EnumLogFont.elfLogFont.lfPitchAndFamily and FIXED_PITCH) = FIXED_PITCH) then
      Add(FaceName);
  end;
  Result := 1;
end;

function EnumFontSizes(var EnumLogFont: TEnumLogFont;
  PTextMetric: PNewTextMetric;
  FontType: Integer; Data: LPARAM): Integer;
  export; stdcall;
var
  S: string; I, V, V2: Integer;
begin
  with TStrings(Data) do
  begin
    if (FontType and TRUETYPE_FONTTYPE) <> 0 then
    begin
      Add('8');
      Add('9');
      Add('10');
      Add('11');
      Add('12');
      Add('14');
      Add('15');
      Add('16');
      Add('18');
      Add('20');
      Add('22');
      Add('24');
      Add('26');
      Add('28');
      Add('36');
      Add('42');
      Add('48');
      Add('72');
      Result := 0;
    end
    else
    begin
      v := Round((EnumLogFont.elfLogFont.lfHeight -
        PTextMetric.tmInternalLeading) * 72 / PixelsPerInch);
      s := IntToStr(v);
      Result := 1;
      for i := 0 to Count - 1 do
      begin
        v2 := StrToInt(Strings[i]);
        if v2 = v then exit;
        if v2 > v then
        begin
          Insert(i, s);
          exit;
        end;
      end;
      Add(s);
    end;
  end;
end;

procedure TSynOptionsForm.sFontNameComChange(Sender: TObject);
var
  DC : HDC;
  FS : string;
begin
  FontPreview.Font.Name := sFontNameCom.Text;
  source.Font := FontPreview.Font;
  DC := GetDC(0);
  try
    FS := sFontsizeCom.text;
    PixelsPerInch := GetDeviceCaps(DC, LOGPIXELSY);
    EnumFontFamilies(DC, PChar(sFontNameCom.Text), @EnumFontSizes, Longint(sFontsizeCom.Items));
    sFontsizeCom.Text := fs;
  finally
    ReleaseDC(0, DC);
  end;
end;

procedure TSynOptionsForm.sFontsizeComChange(Sender: TObject);
begin
  FontPreview.Font.Size := StrToInt(sFontSizeCom.Text);
  source.Font := FontPreview.Font;
end;

procedure TSynOptionsForm.sLineNumberStartKeyDown(Sender: TObject;
  var Key: Word; Shift: TShiftState);
begin
  if not key in [48..57, 65..90, 97..122, 126, 8] then
    key := 0;
end;

procedure TSynOptionsForm.sWordWrapClick(Sender: TObject);
begin
  source.WordWrap.Enabled := sWordWrap.Checked;
  source.WordWrap.Indicator.Visible := sWordWrap.Checked;
end;

procedure TSynOptionsForm.sMaxScrollChange(Sender: TObject);
begin
  Source.MaxScrollWidth := StrToInt(sMaxScroll.Text);
end;

procedure TSynOptionsForm.sRightEdgeMouseMoveClick(Sender: TObject);
begin
  Source.RightEdge.MouseMove := sRightEdgeMouseMove.Checked;
end;

procedure TSynOptionsForm.FormCreate(Sender: TObject);
var
  DC : HDC;
begin
  Source := TSynEditSource.Create(self);
  DC := GetDC(0);
  sFontNameCom.Items.BeginUpdate;
  try
    EnumFontFamilies(DC, nil, @EnumFontName, Longint(sFontNameCom.Items));
  finally
    sFontNameCom.Items.EndUpdate;
    ReleaseDC(0, DC);
  end;
end;

end.
